home *** CD-ROM | disk | FTP | other *** search
Oberon Text | 1995-10-30 | 11.9 KB | 371 lines |
- Syntax10.Scn.Fnt
- Syntax10i.Scn.Fnt
- MODULE RX; (* Andreas Margelisch, 1990 *)
- IMPORT RXA, Oberon, Texts, Viewers, MenuViewers, TextFrames, Display;
- CONST
- blank = 32; (* blank *)
- tab = 9; (* tab *)
- cr = 13; (* carriage return *)
- dq = 34; (* double quotes *)
- noerror = 0;
- strtoolong = -1;
- linetoolong = -2;
- (* nofline = 32000; *) nofline = 20000;
- (* nofrepl = 32000; *) nofrepl = 20000;
- w: Texts.Writer;
- sbeg, send, errorvar : INTEGER;
- sdfa : RXA.DFA;
- stext : Texts.Text;
- stextpos, slinelen : LONGINT;
- sline : ARRAY(nofline+1) OF CHAR;
- sreplaced, casesens, replset : BOOLEAN;
- replstr : ARRAY(nofrepl+1) OF CHAR;
- ch : CHAR;
- PROCEDURE Focus():TextFrames.Frame;
- VAR f : Display.Frame;
- BEGIN
- IF Oberon.FocusViewer.state > 1 THEN
- f := Oberon.FocusViewer.dsc;
- IF ( f # NIL ) & ( f.next # NIL ) & ( f.next IS TextFrames.Frame ) THEN RETURN f.next( TextFrames.Frame ) END;
- END;
- RETURN NIL
- END Focus;
- PROCEDURE MyCAP( ch : CHAR ) : CHAR;
- BEGIN IF ("a" <= ch ) & ( ch <= "z" ) THEN RETURN CAP( ch ) ELSE RETURN ch END;
- END MyCAP;
- PROCEDURE GetText( VAR text : Texts.Text; VAR name : ARRAY OF CHAR; VAR s : Texts.Scanner );
- f : Display.Frame;
- ss : Texts.Scanner;
- v : Viewers.Viewer;
- BEGIN
- Texts.Scan( s );
- text := NIL; name[0] := 0X;
- IF s.class = Texts.Name THEN
- NEW( text ); Texts.Open( text, s.s ); COPY( s.s, name );
- ELSIF ( s.class = Texts.Char ) & ( s.c = "*" ) THEN
- v := Oberon.MarkedViewer();
- f := v.dsc;
- IF ( v.state > 1 ) & ( f # NIL ) & ( f.next # NIL ) & ( f.next IS TextFrames.Frame ) THEN
- IF ( f IS TextFrames.Frame ) THEN
- Texts.OpenScanner( ss, f(TextFrames.Frame ).text, 0 ); Texts.Scan( ss );
- IF ss.class = Texts.Name THEN COPY ( ss.s, name) END;
- END;
- text := f.next( TextFrames.Frame ).text;
- END;
- END;
- END GetText;
- PROCEDURE GetOption( VAR reader : Texts.Reader; VAR opti : BOOLEAN );
- BEGIN
- casesens := TRUE;
- opti := FALSE;
- Texts.Read( reader, ch );
- WHILE ( ORD(ch) = tab ) OR ( ORD(ch) = blank ) OR ( ORD(ch) = cr ) DO Texts.Read( reader, ch ) END;
- IF ch = "\" THEN
- REPEAT
- Texts.Read( reader, ch );
- CASE ch OF
- "c" : casesens := ~casesens |
- "i" : opti := ~opti |
- "~" : RETURN;
- ELSE
- END;
- UNTIL ( ORD(ch) = blank ) OR ( ORD(ch) = cr ) OR ( ORD(ch) =tab );
- END;
- END GetOption;
- PROCEDURE GetStr( VAR reader : Texts.Reader; VAR str : ARRAY OF CHAR );
- VAR strfull, inquotes, first : BOOLEAN;
- strind : INTEGER;
- PROCEDURE Append( chr : CHAR );
- BEGIN
- IF strind < LEN( str ) THEN str[strind] := chr; INC(strind) ELSE strfull := TRUE END;
- END Append;
- BEGIN
- strfull := FALSE; strind := 0; inquotes := FALSE; first := FALSE;
- WHILE ( ORD(ch) = tab ) OR ( ORD(ch) = cr ) OR ( ORD(ch) = blank ) DO Texts.Read( reader, ch ) END;
- WHILE ( ~reader.eot ) & ( ORD(ch) # cr ) DO
- IF ~first & ( ORD(ch) = dq ) THEN inquotes := ~inquotes; first := inquotes; Append( ch );
- ELSE
- IF inquotes & ~casesens THEN Append( MyCAP( ch ) ) ELSE Append( ch ) END;
- first := FALSE;
- END;
- Texts.Read( reader, ch );
- END;
- Append( CHR(0) );
- IF strfull THEN errorvar := strtoolong END;
- END GetStr;
- PROCEDURE RXAErrorHandler( error, pos : INTEGER );
- BEGIN
- CASE error OF
- RXA.noposfree : Texts.WriteString( w,"regular expression too long ( position table full )") |
- RXA.nostatesfree : Texts.WriteString( w,"regular expression too long ( state table full )") |
- RXA.nometaexp : Texts.WriteString( w,"no metasymbol at pos "); Texts.WriteInt( w, pos, 3 );
- Texts.WriteString( w," expected ") |
- RXA.chrleft : Texts.WriteString( w,"regular expression not correct ( ')', ']' or '}' on a wrong place )") |
- RXA.wsubexpr : Texts.WriteString( w,"subexpression, String or shorthands 't' or 'c' at pos "); Texts.WriteInt( w,pos, 3);
- Texts.WriteString( w," expected ") |
- RXA.subexprrest : Texts.WriteString( w,"marked subexpression at pos "); Texts.WriteInt( w,pos, 3);
- Texts.WriteString( w," shouldn't be enclosed by '{ }' ") |
- RXA.wshorthand : Texts.WriteString( w,"wrong shorthand identifier at pos "); Texts.WriteInt( w,pos, 3); Texts.WriteLn( w );
- Texts.WriteString( w,"permitted are : A, a, b, c, d, h, i, l, o, t, w ") |
- RXA.nodfa : Texts.WriteString( w,"replace faild : automata is missing") |
- RXA.repllinefull : Texts.WriteString( w,"replace faild : replacestring is full ") |
- RXA.notnotexp : Texts.WriteString( w,"metasymbol or more than one literal in qutoes after notoperator") |
- RXA.linecopofl : Texts.WriteString( w, "array linecop in RXA.Replace is too small");
- ELSE
- Texts.Write(w, "'"); Texts.Write(w, CHR(error)); Texts.Write(w, "'"); Texts.WriteString( w," at pos ");
- Texts.WriteInt( w,pos, 3); Texts.WriteString( w," expected ");
- END;
- Texts.WriteLn( w );
- Texts.Append( Oberon.Log, w.buf);
- END RXAErrorHandler;
- PROCEDURE RXErrorHandler( text : ARRAY OF CHAR );
- BEGIN
- CASE errorvar OF
- strtoolong, linetoolong : Texts.WriteString( w, text ); Texts.WriteString( w," too long "); |
- ELSE
- Texts.WriteString( w, text );
- END;
- Texts.WriteLn( w );
- Texts.Append( Oberon.Log, w.buf);
- errorvar := noerror;
- END RXErrorHandler;
- PROCEDURE ParseTexts( text : Texts.Text; name : ARRAY OF CHAR; dfa : RXA.DFA; opti : BOOLEAN );
- VAR
- ch : CHAR;
- r : Texts.Reader;
- line, linec : ARRAY(nofline+1) OF CHAR;
- lineind, i, beg, end : INTEGER;
- wtext: Texts.Text;
- x, y: INTEGER;
- v: Viewers.Viewer;
- linefull : BOOLEAN;
- PROCEDURE Append( chr : CHAR );
- BEGIN
- IF lineind < LEN( line ) THEN line[lineind] := chr; INC(lineind) ELSE linefull := TRUE END;
- END Append;
- BEGIN
- Oberon.AllocateUserViewer( Oberon.Mouse.X, x, y );
- wtext := TextFrames.Text("");
- v := MenuViewers.New(TextFrames.NewMenu("RX.Grep", "System.Close System.Copy System.Grow"),
- TextFrames.NewText(wtext, 0), TextFrames.menuH, x, y);
- Texts.OpenReader( r, text, 0 );
- WHILE ( ~ r.eot ) DO
- lineind := 0; linefull := FALSE;
- REPEAT
- Texts.Read( r, ch ); Append( ch );
- UNTIL r.eot OR ( ch = CHR(cr) );
- Append( CHR(0) );
- IF linefull THEN
- RXErrorHandler( " ERROR : line is too long ");
- ELSE
- beg := 0;
- IF casesens THEN
- RXA.Search( dfa, line, beg, end );
- ELSE
- COPY( line, linec ); i := 0; ch := linec[0];
- WHILE ch # 0X DO linec[i] := MyCAP( ch ); INC(i); ch := linec[i] END;
- RXA.Search( dfa, linec, beg, end );
- END;
- IF ( ( end >= 0 ) & (~opti) ) OR ( ( end < 0 ) & opti ) THEN
- i := 0; WHILE i < lineind-1 DO Texts.Write(w, line[i] ); INC(i) END;
- Texts.Append( wtext, w.buf );
- END;
- END;
- END;
- END ParseTexts;
- PROCEDURE Grep*;
- VAR
- opti : BOOLEAN;
- rx : ARRAY(nofline+1) OF CHAR;
- error, erpos : INTEGER;
- dfa : RXA.DFA;
- s : Texts.Scanner;
- text : Texts.Text;
- name : ARRAY 32 OF CHAR;
- BEGIN
- Oberon.Collect(0);
- Texts.OpenScanner( s, Oberon.Par.text, Oberon.Par.pos );
- GetText( text, name, s );
- GetOption( s, opti );
- GetStr( s, rx );
- IF errorvar = noerror THEN
- RXA.New( rx, dfa, error, erpos );
- IF (error = RXA.noerror) & ( text # NIL ) THEN
- ParseTexts( text, name, dfa, opti )
- ELSE
- RXAErrorHandler( error, erpos )
- END;
- ELSE
- RXErrorHandler("regular expression");
- END;
- END Grep;
- PROCEDURE SetSearch*;
- VAR
- opti : BOOLEAN;
- rx : ARRAY(nofline+1) OF CHAR;
- ind : INTEGER;
- error, erpos : INTEGER;
- r : Texts.Reader;
- BEGIN
- Oberon.Collect(0);
- Texts.OpenReader( r, Oberon.Par.text, Oberon.Par.pos );
- GetOption( r, opti );
- GetStr( r, rx );
- IF errorvar = noerror THEN
- RXA.New( rx, sdfa, error, erpos );
- IF error # RXA.noerror THEN RXAErrorHandler( error, erpos ) END;
- ELSE
- RXErrorHandler("regular expression");
- END;
- (* RXA.Dump( sdfa, w ); Texts.Append( Oberon.Log, w.buf ); *)
- END SetSearch;
- PROCEDURE SetReplace*;
- VAR r : Texts.Reader;
- BEGIN
- replset := TRUE;
- Texts.OpenReader( r, Oberon.Par.text, Oberon.Par.pos );
- Texts.Read(r, ch); (* << mmb *)
- GetStr( r, replstr );
- IF errorvar # noerror THEN RXErrorHandler("replace pattern"); END;
- END SetReplace;
- PROCEDURE SearchPattern( text : Texts.Text; textpos : LONGINT );
- VAR
- r : Texts.Reader;
- beg, end, lineind : INTEGER;
- ch : CHAR;
- line : ARRAY(nofline+1) OF CHAR;
- linelen : LONGINT;
- linefull : BOOLEAN;
- PROCEDURE Append( chr : CHAR );
- BEGIN
- IF lineind < LEN( line ) THEN
- IF ~casesens THEN line[lineind] := MyCAP( chr ) ELSE line[lineind] := chr END;
- INC(lineind);
- ELSE
- linefull := TRUE;
- END;
- END Append;
- BEGIN
- end := -1;
- Texts.OpenReader( r, text, textpos );
- WHILE ( ~ r.eot ) & ( end < 0 ) DO
- lineind := 0; linefull := FALSE;
- textpos := Texts.Pos( r );
- REPEAT
- Texts.Read( r, ch );
- Append( ch );
- UNTIL r.eot OR ( ch = CHR(cr) );
- linelen := lineind;
- Append( CHR(0) );
- IF linefull THEN
- RXErrorHandler( " ERROR : line is too long ");
- ELSE
- beg := 0;
- RXA.Search( sdfa, line, beg, end );
- END;
- END;
- IF end >= 0 THEN
- stext := text; stextpos := textpos; slinelen := linelen; sbeg := beg; send := end; sreplaced := FALSE; COPY( line, sline );
- END;
- END SearchPattern;
- PROCEDURE Search*;
- VAR
- frame : TextFrames.Frame;
- textpos : LONGINT;
- BEGIN
- errorvar := noerror;
- frame := Focus();
- IF frame # NIL THEN
- IF frame.hasCar THEN textpos := frame.carloc.pos ELSE textpos := 0 END;
- SearchPattern( frame.text, textpos );
- IF ( ~sreplaced ) & ( frame.text = stext ) THEN
- Oberon.RemoveMarks( frame.X, frame.Y, frame.W, frame.H );
- TextFrames.RemoveSelection( frame );
- TextFrames.RemoveCaret( frame );
- IF stextpos + send > TextFrames.Pos( frame, frame.X + frame.W, frame.Y ) THEN
- TextFrames.Show( frame, stextpos + send-200 );
- END;
- TextFrames.SetSelection( frame, stextpos + sbeg, stextpos + send );
- TextFrames.SetCaret( frame, stextpos + send );
- END
- END;
- END Search;
- PROCEDURE Replace*;
- VAR
- error, pos, i : INTEGER;
- frame : TextFrames.Frame;
- textpos : LONGINT;
- BEGIN
- IF ( ~sreplaced ) & replset THEN
- frame := Focus();
- IF frame # NIL THEN
- IF frame.hasCar & ( frame.carloc.pos = stextpos + send ) THEN
- RXA.Replace( sdfa, sline, replstr, sbeg, send, error, pos );
- sreplaced := error = RXA.noerror;
- IF sreplaced THEN
- Oberon.RemoveMarks( frame.X, frame.Y, frame.W, frame.H );
- TextFrames.RemoveSelection( frame );
- TextFrames.RemoveCaret( frame );
- Texts.Delete( frame.text, stextpos, stextpos + slinelen );
- i := 0; WHILE( i < LEN( sline ) ) & ( sline[i] # 0X ) DO Texts.Write( w, sline[i] ); INC(i) END;
- Texts.Insert( frame.text, stextpos, w.buf );
- textpos := stextpos + pos;
- SearchPattern( frame.text, textpos );
- IF ~sreplaced THEN
- IF stextpos + send > TextFrames.Pos( frame, frame.X + frame.W, frame.Y ) THEN
- TextFrames.Show( frame, stextpos + send-200 );
- END;
- TextFrames.SetSelection( frame, stextpos + sbeg, stextpos + send );
- TextFrames.SetCaret( frame, stextpos + send );
- ELSE
- IF frame.org # textpos - 200 THEN TextFrames.Show( frame, textpos-200 ) END;
- TextFrames.SetCaret( frame, textpos );
- END;
- ELSE
- RXAErrorHandler( error, pos );
- END;
- END
- END;
- END;
- END Replace;
- PROCEDURE ReplaceAll*;
- VAR
- frame : TextFrames.Frame;
- textpos : LONGINT;
- error, pos, i : INTEGER;
- BEGIN
- errorvar := noerror;
- frame := Focus();
- IF ( frame # NIL ) & replset THEN
- IF frame.hasCar THEN textpos := frame.carloc.pos ELSE textpos := 0 END;
- Oberon.RemoveMarks( frame.X, frame.Y, frame.W, frame.H );
- TextFrames.RemoveSelection( frame );
- TextFrames.RemoveCaret( frame );
- LOOP
- SearchPattern( frame.text, textpos );
- IF ~sreplaced THEN
- RXA.Replace( sdfa, sline, replstr, sbeg, send, error, pos );
- IF error = RXA.noerror THEN
- sreplaced := TRUE;
- Texts.Delete( frame.text, stextpos, stextpos + slinelen );
- i := 0; WHILE( i < LEN( sline ) ) & ( sline[i] # 0X ) DO Texts.Write( w, sline[i] ); INC(i) END;
- Texts.Insert( frame.text, stextpos, w.buf );
- textpos := stextpos + pos;
- ELSE
- RXAErrorHandler( error, pos );
- RETURN
- END;
- ELSE
- EXIT;
- END;
- END
- END;
- END ReplaceAll;
- BEGIN
- Texts.OpenWriter( w );
- errorvar := noerror;
- replset := FALSE;
- sreplaced := TRUE;
- sdfa := NIL;
- END RX.
-